package org.loujiarong.yugioh.gameplay.duel;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.loujiarong.yugioh.gameplay.card.Card;
import org.loujiarong.yugioh.gameplay.database.CardNameClassMappingDAO;

public class Player
{
   protected String name;
   protected int lifePoint = 8000;

   protected Hand hand;  
   protected MainDeck mainDeck;
   protected SideDeck sideDeck;
   protected ExtraDeck extraDeck;
   protected Graveyard graveYard;

   protected PlayingField field;
   protected BanishedArea banishedArea;
   
   public Player(String name) {
	   this.name = name;
	   hand = new Hand();
	   mainDeck = new MainDeck();
	   sideDeck = new SideDeck();
	   extraDeck = new ExtraDeck();
	   graveYard = new Graveyard();
	   field = new PlayingField();
	   banishedArea = new BanishedArea();
   }
   
	public boolean draw(int number) {
		for(int i=0;i<number;++i){
			Card card = mainDeck.poll();
			if (card != null) {
				hand.add(card);
			} 
			else {
				return false;
			}
		}
		return true;
	}
   
	public void loadDeck(File deckFile) throws Exception {
		try { 
			BufferedReader br = 
				new BufferedReader(
					new InputStreamReader(
						new FileInputStream(deckFile),"UTF-8"));
			String line;
			int lineNum = 0;
		    mainDeck = new MainDeck();
			sideDeck = new SideDeck();
			extraDeck = new ExtraDeck();
			String loadingDeck = "Main";
			Pattern cardPattern = Pattern.compile(".*\\[(.+)\\]#*");
			Matcher cardMatcher;
			
			while((line = br.readLine()) != null) {
				 ++ lineNum;
				 cardMatcher = cardPattern.matcher(line);		

				 if(cardMatcher.matches()) {
					 System.out.println(
							 cardMatcher.group(1) + " " + CardNameClassMappingDAO.getClassNameFromCn(cardMatcher.group(1)));
					 Card card = (Card)Class.forName("org.loujiarong.yugioh.card." +
							 CardNameClassMappingDAO.getClassNameFromCn(
									 cardMatcher.group(1))).newInstance();
					 card.setOwner(this);
					 card.setController(this);
					 if(loadingDeck.equals("Main")) {
						 mainDeck.add(card);
					 }
					 if(loadingDeck.equals("Side")) {
						 sideDeck.add(card);
					 }
					 if(loadingDeck.equals("Extra")) {
						 extraDeck.add(card);
					 }
				 }
				 else if(Pattern.compile(".*#+").matcher(line).matches()){
					 loadingDeck = "Side";
					 continue;
				 }
				 else if(Pattern.compile(".*=+").matcher(line).matches()){
					 loadingDeck = "Extra";
					 continue;
				 }
				 else if(Pattern.compile(".*\\$+").matcher(line).matches()){
					 break;
				 }			 
				 else {
					 throw new Exception("Deck File Format Error at line " 
							 + lineNum + " : " + line); 
				 }
			}
			mainDeck.shuffle();
						
		} catch(Exception ex) {
			throw ex;
		}
	}
   
   public int getLifePoint()
   {
      return lifePoint;
   }
   public void setLifePoint(int lifePoint)
   {
      this.lifePoint = lifePoint;
   }
   public MainDeck getMainDeck()
   {
      return mainDeck;
   }
   public void setMainDeck(MainDeck mainDeck)
   {
      this.mainDeck = mainDeck;
   }
   public SideDeck getSideDeck()
   {
      return sideDeck;
   }
   public void setSideDeck(SideDeck sideDeck)
   {
      this.sideDeck = sideDeck;
   }
   public ExtraDeck getExtraDeck()
   {
      return extraDeck;
   }
   public void setExtraDeck(ExtraDeck extraDeck)
   {
      this.extraDeck = extraDeck;
   }
   public PlayingField getField()
   {
      return field;
   }
   public void setField(PlayingField field)
   {
      this.field = field;
   }
   public BanishedArea getRemovedFromPlayArea()
   {
      return banishedArea;
   }
   public void setRemovedFromPlayArea(BanishedArea removeFromPlayArea)
   {
      this.banishedArea = removeFromPlayArea;
   }
	public Hand getHand() {
		return hand;
	}
	public void setHand(Hand hand) {
		this.hand = hand;
	}
	public Graveyard getGraveYard() {
		return graveYard;
	}
	public void setGraveYard(Graveyard graveYard) {
		this.graveYard = graveYard;
	}
	public String toString() {
		return name;
	}
	
}
